/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package cz.muni.fi.pa165.mushroom.website.web;

import cz.muni.fi.pa165.mushroom.website.dto.GathererDto;
import cz.muni.fi.pa165.mushroom.website.servicesImpl.GathererServiceImpl;
import java.util.List;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.Before;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.LocalizableMessage;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import static net.sourceforge.stripes.controller.DispatcherHelper.getPageContext;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.LocalizableError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import net.sourceforge.stripes.validation.ValidationErrors;
import net.sourceforge.stripes.validation.ValidationMethod;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.util.SimpleByteSource;
import org.apache.taglibs.standard.functions.Functions;

/**
 * Action bean for gatherers
 * 
 * @author Pavel Démuth
 */
public class GathererActionBean extends BasicActionBean{  
    
 
    @SpringBean
    protected GathererServiceImpl gathererServiceImpl;
     
    private static RandomNumberGenerator saltGenerator = new SecureRandomNumberGenerator();
    private String password;
    private String newPassword;
    private String reenteredNewPassword;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getNewPassword() {
        return newPassword;
    }

    public void setNewPassword(String newPassword) {
        this.newPassword = newPassword;
    }

    public String getReenteredNewPassword() {
        return reenteredNewPassword;
    }

    public void setReenteredNewPassword(String reenteredNewPassword) {
        this.reenteredNewPassword = reenteredNewPassword;
    }
    
    
    
   
    @ValidateNestedProperties(value = {
            @Validate(on = {"add"}, field = "username", required = true),
            @Validate(on = {"add", "save"}, field = "firstName", required = true),
            @Validate(on = {"add", "save"}, field = "lastName", required = true),
            @Validate(on = {"add", "save"}, field = "info", required = false),
            @Validate(on = {"add"}, field = "password", required = true),
           
    })
   private GathererDto gathererDto;
   
    
    @DefaultHandler
    public Resolution all() {
        return new ForwardResolution("/protected/regIndex.jsp");

    }
    
    private GathererDto setPassword(GathererDto g) {
        String salt = saltGenerator.nextBytes().toBase64();
        g.setSalt(salt);
        Sha256Hash hash = new Sha256Hash(g.getPassword(), new SimpleByteSource(salt).getBytes());
        g.setPassword(hash.toHex());        
        return g;
    }
    
    public Resolution add() {
        gathererServiceImpl.createGatherer(setPassword(gathererDto));
        getContext().getMessages().add(new LocalizableMessage("gatherer.add.message", escapeHTML(gathererDto.getUsername())));        
        return new RedirectResolution("/login.jsp");
    }    
    
    public Resolution delete() {        
        gathererServiceImpl.removeGatherer(gathererDto);
        getContext().getMessages().add(new LocalizableMessage("gatherer.delete.message", escapeHTML(gathererDto.getUsername())));
        return new ForwardResolution("/showGatherers.jsp");
    }
    
    @Before(stages = LifecycleStage.BindingAndValidation, on = {"edit", "save"})
    public void loadGathererFromDatabase() {
        String ids = getContext().getRequest().getParameter("gathererDto.id");
        if (ids == null) return;
        gathererDto = gathererServiceImpl.findGatherer(Long.parseLong(ids));
    }
 
    public Resolution edit() {
        gathererDto = gathererServiceImpl.findGathererByUsername((String)SecurityUtils.getSubject().getPrincipal());        
        return new ForwardResolution("/protected/editGatherer.jsp");
    }
 
     public Resolution editGatherer() {
        String ids = getContext().getRequest().getParameter("gatherer");
        gathererDto = gathererServiceImpl.findGathererByUsername((String)SecurityUtils.getSubject().getPrincipal());         
        return new ForwardResolution("/protected/editGatherer.jsp");
    }
    
    public Resolution save() {        
        gathererServiceImpl.updateGatherer(gathererDto);
        getContext().getMessages().add(new LocalizableMessage("gatherer.update.message", escapeHTML(gathererDto.getUsername())));
        return new RedirectResolution(this.getClass(), "all");
    }
    
    public Resolution cancel(){
        return new RedirectResolution(this.getClass(), "all"); 
    }
    

    public GathererDto getGathererDto() {
        return gathererDto;
    }

    public void setGathererDto(GathererDto gathererDto) {
        this.gathererDto = gathererDto;
    }   
    
    
    
    public List<GathererDto> getGatherers() {
        return gathererServiceImpl.listGatherers();
    }
    
    
    
    @ValidationMethod(on = {"changePassword"})
    public void validateOnChangePass(ValidationErrors errors) {
        gathererDto = gathererServiceImpl.findGathererByUsername((String)SecurityUtils.getSubject().getPrincipal());
        
        String salt = gathererDto.getSalt();
        if(password == null){
            errors.add("password", new LocalizableError("gatherer.changePass.currentPass")); 
            return;
        }
        Sha256Hash hash = new Sha256Hash(password, new SimpleByteSource(salt).getBytes());
        
       
        if (password == null || !hash.toHex().equals(gathererDto.getPassword())) {
            errors.add("password", new LocalizableError("gatherer.changePass.currentPass"));
        }
        
        if(newPassword == null || reenteredNewPassword == null || 
                !newPassword.equals(reenteredNewPassword)) {
            errors.add("password", new LocalizableError("gatherer.add.password.mismatch"));
        }
    }
    
    public Resolution changePassword(){
        gathererDto = gathererServiceImpl.findGathererByUsername((String)SecurityUtils.getSubject().getPrincipal());       
       
        String salt = saltGenerator.nextBytes().toBase64();
        gathererDto.setSalt(salt);
        Sha256Hash hash = new Sha256Hash(newPassword, new SimpleByteSource(salt).getBytes());
        gathererDto.setPassword(hash.toHex());
        gathererServiceImpl.updateGatherer(gathererDto);
        getContext().getMessages().add(new LocalizableMessage("changedPass"));
        return new ForwardResolution("/protected/regIndex.jsp");
    }
   
}